/**
 * @file CRhoTabAlg.cpp Implementácia triedy CRhoTabAlg.
 *
 * @author Martin Kosorinský.
 * @date 1.4.2009.
 */

#include "CRhoTabAlg.hpp"

bool CRhoTabAlg::computeLogarithm(big vysledok, int distParam) {

    tracer << "Pollard-Rho (tab based on";
#ifdef ECDLP_USING_HASHTABLE
    tracer << " <unordered_map>):" << endl;
#else
    tracer << " <map>):" << endl;
#endif

    if (!isInitialized()) {
        cerr << "Nie je inicializovaný kontext!" << endl;
        return false;
    }

    big a = mirvar(1);
    big b = mirvar(0);
    big dist = mirvar(1);
    epoint* X = epoint_init();
    epoint_copy(G, X);

    big tmp = mirvar(0); // pomocna premenna

    sftbit(dist, distParam, dist);

    CRhoTable tabulka;
    CRhoTable::const_iterator it;

    while (1) {
        makeStep(X, a, b, tmp);
        if (isDistinguished(X, dist)) {
            if ((it = tabulka.find(X)) != tabulka.end()) {
                if (computeIndex(a, b, it->second.first, it->second.second, vysledok)) {
                    mirkill(a);
                    mirkill(b);
                    epoint_free(X);
                    mirkill(tmp);
                    return true;
                }
            }
            tabulka.add(X, a, b);
        }
    }
    mirkill(a);
    mirkill(b);
    mirkill(dist);
    mirkill(tmp);
    epoint_free(X);
    return false;
}

bool CRhoTabAlg::isDistinguished(epoint * X, big distMod) {

    bool retVal = false;
    if (!point_at_infinity(X)) {
        epoint_get(X, bigBuffer[0], bigBuffer[1]);

        if (divisible(bigBuffer[1], distMod)) {
            retVal = true;
        }
    }

    return retVal;
}
